﻿using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Build.Framework.XamlTypes;
using Microsoft.VisualStudio.ProjectSystem.Properties;

namespace Red.Scripts.Project.Utility
{
    internal static class DepotSearch
    {
        #region Private Functions

        private static string BuildDisplayName( string root, string path )
        {
            // + 1 includes the directory separator
            return $"{Path.GetFileNameWithoutExtension( path )} ({path.Substring( root.Length + 1 )})";
        }

        private static IEnumerable<string> FindFiles( string root, string filter )
        {
            if( Directory.Exists( root ) )
                return Directory.GetFiles( root, filter, SearchOption.AllDirectories );

            return new string[ 0 ];
        }

        private static async Task<IEnumerable<string>> FindFilesAsync( string root, string filter )
        {
            return await Task.Run( () => FindFiles( root, filter ) );
        }

        private static List<IEnumValue> BuildFileList( string root, IEnumerable<string>[] manyPaths )
        {
            IEnumerable<string> paths = manyPaths.SelectMany( result => result );

            return ( from path in paths select (IEnumValue)new PageEnumValue( new EnumValue() { Name = path, DisplayName = BuildDisplayName( root, path ) } ) ).ToList();
        }

        private static async Task<List<IEnumValue>> BuildFileListAsync( string root, IEnumerable<string>[] manyPaths )
        {
            return await Task.Run( () => BuildFileList( root, manyPaths ) );
        }

        #endregion Private Functions

        #region Public Functions

        public static async Task<ICollection<IEnumValue>> BuildFileList( string filter, params object[] productionSubdirs )
        {
            DefinesAccessor defines = new DefinesAccessor();
            await defines.Load();

            string workspaceRoot = defines.ActiveWorkspaceRoot;
            if ( !string.IsNullOrEmpty( workspaceRoot ) )
            {
                List<Task<IEnumerable<string>>> tasks = new List<Task<IEnumerable<string>>>();

                string depotRoot = Path.Combine( defines.ActiveWorkspaceRoot, "r6", "depot" );
                foreach ( string subdir in productionSubdirs )
                {
                    string path = Path.Combine( depotRoot, "base", subdir );
                    tasks.Add( FindFilesAsync( path, filter ) );
                }

                string gyms = Path.Combine( depotRoot, "non_production", "gyms" );
                tasks.Add( FindFilesAsync( gyms, filter ) );

                string qa = Path.Combine( depotRoot, "non_production", "qa" );
                tasks.Add( FindFilesAsync( qa, filter ) );

                var paths = await Task.WhenAll( tasks );

                return await BuildFileListAsync( depotRoot, paths );
            }

            return new IEnumValue[ 0 ];
        }

        #endregion Public Functions
    }
}